Skip to content

fix(chat): make waiting visible and keep conversations readable - #5309

Merged
huangruiteng merged 3 commits into
mainfrom
codex/app-live-query-recovery
Sep 30, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/app-live-query-recovery

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

A message could appear submitted while executor startup showed no reply or progress. The overview receipt also hid activity and turn controls available in the full conversation. This change shows a receipt before session preparation, then observed activity and elapsed time, with cancellation before dispatch and existing exact-turn controls after acceptance.

The shared manager/Goal conversation also preserves upward reading during streaming, provides a return-to-latest action, expands multiline drafts, and removes the suggestion strip from an established conversation. The existing App conversation RFC records the research and observable acceptance boundaries.

Intended base: main. Owner: the existing TypeScript conversation presentation and Chat transport; no new capability, provider, scheduler or backend decision owner.

Scope And Continuation

Complete within this presentation slice. It does not claim to cure provider startup timeouts, implement completion notifications, persist browser elapsed time across restarts, or complete delegated work. CLI/Lark behavior is unchanged because the affected path is the App/browser conversation renderer and session-preparation fetch.

A real read-only goal-wording request succeeded after repairing an installed CLI selection. An earlier live request still timed out before executor turn acknowledgement; sustained startup/recovery remains part of the existing App conversation acceptance, not certified by this UI change.

Validation

  • Tested revision: b42dc14d45f086a6b72d13a6193488f034ff10f0
  • Run state: finished.
  • Input classes: synthetic, public_fixture, authorized_private_read_only.
Check kind Result Evidence / limitation
static passed TypeScript typecheck and python scripts/chat_bundle.py build; source/delivery verification.
integration passed Packaged conversation-startup: delayed connection, immediate receipt, cancellation without turn dispatch, retry and failure.
integration passed Packaged conversation-activity: incremental SSE, stable elapsed across views, quiet wait, steering/interruption races, mobile/keyboard and preserved reading position.
integration passed Packaged conversation-input: multiline draft growth, newline without submission, Goal/manager routing, explicit preview and retained drafts.
regression_parity passed Complete packaged workspace browser suite: all 25 scenarios on the final source, including Chat recovery, original-route returns, goal drafts and typed action forms. Synthetic provider boundaries and existing journey qualification gaps remain explicit.
real_backend passed Existing Codex Sol read-only conversation returned a goal-wording answer in 23 seconds through the packaged candidate. Installed App read back the stored result. No research execution was requested.
real_backend failed An earlier request on the prior installed executor timed out before turn acknowledgement. No claim of sustained timeout recovery.
static passed Risk-selected premerge: 16 checks, zero failures; exact-scope change-quality receipt passed.

Initial validation caught and corrected EOF whitespace, missing root TypeScript dependencies and a concurrent-edit guard. CI then exposed stale tests that used a suggestion button to infer turn completion after that button was removed from established conversations. The follow-up observes pending replies directly and opens configuration from the overview; the complete packaged browser suite now passes. The final branch is rebased on main 350f0f3 and removes a duplicate composer height effect. The same startup regression fails on that base and passes on this head. Local architecture replay found two unchanged baseline failures: generated-twin census expects one generated pair but sees two, and the developer book lacks its v1.2.3 release anchor (tracked by #5318). Both fail with the same identity and detail on base and head, outside this presentation path. Merge readiness must resolve these separately; neither failure is hidden or weakened. The prior live Sol result is reused because its executor path is unchanged by the rebase/refinement; a new paid model call was not made. Generated assets and live evidence remain outside Git.

Frontend / Visual Evidence

UI impact: changed. Synthetic screenshots are attached in the conversation: before startup receipt, after overview waiting, desktop conversation and narrow conversation. The before image uses the previously installed release renderer with a synthetic request; after images use the candidate packaged renderer and synthetic SSE.

Attention review: one observed activity line plus elapsed time; details expand on demand. Quiet waiting is explicit, not a fake percentage or changing phase. Controls remain scoped to the actual turn. Drafts grow within 120px, active conversations lose a redundant suggestion strip, and streaming no longer steals the reader's position.

Type of Change

  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Public docs or presentation surface (dashboard)

Boundary Checklist

  • No private state, credentials, raw traces, internal links or machine paths in the diff or public evidence.
  • Shared-authority fixture impact: N/A; no authority-store or state-migration change.
  • Related refactor applied: one shared activity/control component replaces duplicated overview/full-conversation behavior; the backend remains authoritative for accepted-turn effects.
  • Every commit has DCO sign-off.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Visual acceptance — synthetic request and public fixtures only.

Before: the prior installed renderer shows the submitted request while startup has no assistant receipt.
After: candidate packaged overview shows actual activity, elapsed wait and exact-turn controls; the narrow conversation retains the same controls and a compact composer.

conversation-startup-before conversation-waiting-overview conversation-activity-mobile

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/app-live-query-recovery branch from aee7880 to b42dc14 Compare September 29, 2026 19:09

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

English verdict: APPROVE - head b42dc14

未发现这份完整差异的阻塞问题。这是可独立验收的 App 对话呈现增量;原生执行器持续恢复与团队采用仍未验收,不能据此宣布整个管家旅程完成。

动机

用户发出普通问题后,执行器连接可能很慢,原先必须等连接结束才出现答复占位,消息容易让人感觉丢了。此次目标是让一次发送立即可见,等待、纠偏和中断都有明确对象,同时保留输入、部分答复和阅读位置。普通问题直接发送,不增加必经确认步骤。

改动思路

沿既有发送入口补上准备阶段,再把活动与当前回合控制收敛到共用组件。管家、Goal 和总览中的答复使用同一套呈现;真正的执行状态、会话、回合和幂等操作仍由现有 Chat API 负责。单独加转圈无法解释是否已送到执行器,另外搭进度服务又会引入重复状态,因此这个边界与现有所有者更合适。

具体改动

关键代码讲解

  • sendManagerQuestion 在创建或恢复 Session 之前写入本地接收状态。准备期间取消只中止连接请求;真正提交开始后移除这个取消入口,转而等待服务器给出回合身份,不把已提交工作说成未发送。
  • MessageActivity 共用于完整时间线与总览回执,呈现实际报告的最近活动、耗时和无新活动的等待。追加指令在响应不确定时保留原操作标识和草稿,明确未送达后才允许新的标识;回合结束仍保留未发送文字。
  • interruptManagerTurn 复用既有会话与当前回合校验。拒绝、错误回执或晚到回执不能中止另一轮;部分输出继续可读。输入框只保留一个高度调整 effect,向上阅读时新输出不再抢走滚动位置。

整份差异包含八个产品文件、七个浏览器验证文件和两份双语 RFC,没有生成资源、私有运行记录或新队列。最后一次修订删除了重复输入框高度逻辑,并针对退役的快捷提示更新测试入口。

验证:最终源码的 TypeScript 构建和交付资源验证通过;打包浏览器的全部 25 个场景通过,覆盖延迟连接、发送前取消、失败重试、纠偏回执不确定、中断错配、结束竞态、手机宽度及保留阅读位置。相同连接等待反例在不可变基线 350f0f3 上因接收状态缺失而失败,在本次 head 上通过。16 项风险选择检查与三项直接差异检查通过,精确差异质量回执有效。已有证据的源码、基线、依赖和声明范围复核后未失效,没有重新调用付费模型。

对主干的风险

浏览器场景使用真实增量 HTTP/SSE 传输和合成执行器事件,因此证明的是打包 UI 的生命周期、回执和操作行为,不能证明原生 Provider 的取消、启动或持续恢复。历史消息缺少计时字段时不伪造耗时;本轮计时是浏览器投影,刷新后的持续计时不在此范围。桌面和 390 像素宽手机整屏已经检查,当前答复、等待说明和作用于本轮的按钮可以一起理解。

有两项原有本地失败,已分别在基线和当前 head 用同一命令复现,身份和错误细节一致:生成双运行时检查在 test_turn_contract_generation.py:263 预期一个生成对却看到两个;开发者书首页缺少 v1.2.3 发布锚点,后者由 #5318 跟进。此差异没有触及两者的因果路径,修改的不变量有独立通过证据。它们作为独立合并就绪问题保留,没有缩小扫描、提高限额或隐藏失败;本审查也不声明全仓检查全绿。

我的整体评价

我同意这个有界增量进入维护者合并决策:它解决真实可复现的等待不可见问题,复用通用组件,且保持执行权和回传归属。剩余重点是合并后安装真实 App,继续验证原生启动、恢复和原入口结果回传;团队独立验收与采用仍沿已有路线推进。产品运行路径按仓库规则留给维护者合并,本次审查不自动合并。

@huangruiteng
huangruiteng merged commit cb721e1 into main Sep 30, 2026
30 of 36 checks passed
@huangruiteng
huangruiteng deleted the codex/app-live-query-recovery branch September 30, 2026 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant